package logic

import (
	"fmt"
	"log"
	"time"

	. "mlgmd.com/hearsay/base"
	"mlgmd.com/hearsay/entities"
	"mlgmd.com/hearsay/logic/push"
	"mlgmd.com/hearsay/utils"
	"xorm.io/xorm"
)

// RunTask 执行冻结铜板的任务
func RunTask() (err error) {
	defer Error(&err)
	log.Println("Freeze start")
	if Must2(DB.Table(&entities.TaskRecord{}).Where("start_time > ?", time.Now().Unix()-24*60*60-1000).Exist()) {
		log.Println("Freeze already")
		return fmt.Errorf("最近已执行过")
	}
	rec := entities.TaskRecord{
		StartTime: time.Now().Unix(),
	}
	Must2(DB.Insert(&rec))

	Must2(DB.Transaction(func(DB *xorm.Session) (interface{}, error) {
		log.Println("Freeze do")
		unlocks := make([]entities.HearsayUnlock, 0)
		Must(DB.Table([]any{&entities.Hearsay{}, "h"}).
			Join("INNER", []any{&entities.HearsayUnlock{}, "hu"}, "hu.hearsay_id=h.id").
			Where("h.deleted_time = 0").
			Where("hu.created_time < ? and hu.result=0", time.Now().Unix()-24*60*60).Find(&unlocks))
		users := make([]entities.User, 0)
		Must(DB.In("id", utils.Map(unlocks, utils.Key[entities.HearsayUnlock]("user"))).Find(&users))
		um := map[int]*struct {
			Coin   int
			Frozen int
		}{}
		for _, user := range users {
			um[user.Id] = &struct {
				Coin   int
				Frozen int
			}{Coin: user.Coin, Frozen: 0}
		}
		for _, unlock := range unlocks {
			if u, has := um[unlock.UserId]; has && u.Coin > u.Frozen {
				u.Frozen++
				Must2(DB.ID(unlock.Id).Incr("frozen_coin").Update(&entities.HearsayUnlock{}))
			}
		}
		for id, u := range um {
			if u.Frozen > 0 {
				Must2(DB.ID(id).Decr("coin", u.Frozen).Update(&entities.User{}))
				_ = push.Send(id, id, fmt.Sprintf("你有%d个铜板被暂时冻结，原因是有已解锁的传闻未点赞或点踩，请及时处理。", u.Frozen), "", 0, true)
			}
		}
		Must2(DB.Table(&entities.TaskRecord{}).ID(rec.Id).Update(map[string]any{
			"finish_time": time.Now().Unix(),
			"result":      "completed",
		}))
		return nil, nil
	}))
	log.Println("Freeze completed")
	return nil
}

// Release 释放被冻结的铜板
func Release(DB *xorm.Session, hearsay entities.Hearsay, unlock entities.HearsayUnlock) {
	if unlock.FrozenCoin > 0 {
		Must2(DB.ID(unlock.UserId).Incr("coin", unlock.FrozenCoin).Update(&entities.User{}))
		_ = push.Send(hearsay.CreatorId, unlock.UserId, fmt.Sprintf("释放被冻结的铜板:%d", unlock.FrozenCoin), "", 0, true)
	}
}

// ReleaseAll 释放所有被冻结的铜板
func ReleaseAll() {

}
